package com.atguigu.srb.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.srb.common.exception.Assert;
import com.atguigu.srb.common.exception.SrbException;
import com.atguigu.srb.common.result.ResponseEnum;
import com.atguigu.srb.common.util.HttpClientUtils;
import com.atguigu.srb.common.util.JwtUtils;
import com.atguigu.srb.core.config.WxLoginInfoProperties;
import com.atguigu.srb.core.pojo.entity.UserInfo;
import com.atguigu.srb.core.service.UserInfoService;
import com.atguigu.srb.core.service.UserLoginRecordService;
import com.atguigu.srb.core.service.WxUserInfoService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;

/**
 * ClassName: WxUserInfoServiceImpl
 * Package: com.atguigu.srb.core.service.impl
 * Description:
 *
 * @Author 王晓龙
 * @Create 2023/4/3 12:33
 * @Version 1.0
 */
@Service
public class WxUserInfoServiceImpl implements WxUserInfoService {
    @Resource
    UserInfoService userInfoService;

    @Override
    public String wxLogin(HttpSession session) {
        //生成token
        String token = UUID.randomUUID().toString();
        System.out.println("生成token：" + token);
        //将token放入session缓存中
        session.setAttribute("assertToken", token);
        return "redirect:" + WxLoginInfoProperties.API +//wx二维码接口地址
                //我们的应用注册到wx平台时分配的唯一id
                "?appid=" + WxLoginInfoProperties.APPID +
                //用户扫码授权后wx让浏览器重定向访问的回调接口地址
                "&redirect_uri=" + WxLoginInfoProperties.REDIRECTURI +
                "&response_type=code" +
                "&scope=snsapi_login" + //wx登录授权后的token的作用域
                "&state=" + token +
                "#wechat_redirect";
    }

    @Override
    public String callback(String code, String state, HttpSession session, HttpServletRequest request) {
        //对token进行校验
        String requestToken = String.valueOf(session.getAttribute("assertToken"));
        System.out.println("获取token：" + requestToken);
        Assert.assertNotTrue(StringUtils.isEmpty(state) || !requestToken.equals(state), ResponseEnum.WEIXIN_CALLBACK_TOKEN_ERROR);
        session.removeAttribute("assertToken");
        //1.通过code获取access_token和openid
        String path = WxLoginInfoProperties.CALLBACKURL +
                "?appid=" + WxLoginInfoProperties.APPID +
                "&secret=" + WxLoginInfoProperties.SECRET +
                "&code="+ code +
                "&grant_type=authorization_code";

        HttpClientUtils client = new HttpClientUtils(path);
        UserInfo userInfo = null;

        try {
            //发起请求
            client.get();
            //获取响应体-json字符串
            String content = client.getContent();
            //判断响应是否报错
            Map<String, Object> contentMap = JSON.parseObject(content, Map.class);
            if (contentMap.containsKey("errcode")){
                throw new SrbException(Integer.parseInt(contentMap.get("errcord").toString()),
                        contentMap.get("errmsg").toString());
            }
            //从响应结果中获取token
            Object accessToken = contentMap.get("access_token");
            //获取微信用户的openid，每人唯一
            Object openid = contentMap.get("openid");
            //根据openid获取用户，如果没有，则将当前微信用户的信息存入数据库，再次获取用户信息
            userInfo = userInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class)
                    .eq(UserInfo::getOpenid, openid));
            if (userInfo==null){
                path = WxLoginInfoProperties.USERINFOURL +
                        "?access_token="+ accessToken +
                        "&openid="+ openid;
                //再次获取微信用户信息
                client = new HttpClientUtils(path);
                client.get();
                content = client.getContent();
                contentMap = JSON.parseObject(content, Map.class);
                String nickName = contentMap.get("nickname").toString();
                String headimgurl = contentMap.get("headimgurl").toString();

                userInfo = new UserInfo();
                userInfo.setNickName(nickName);
                userInfo.setHeadImg(headimgurl);
                userInfo.setIntegral(0);
                userInfo.setOpenid(String.valueOf(openid));
                userInfo.setSalt("wx");
                userInfoService.save(userInfo);
            }
            if ((System.currentTimeMillis()-userInfo.getCreateTime().getTime())>=7*24*60*60*1000){
                path = WxLoginInfoProperties.USERINFOURL +
                        "?access_token="+ accessToken +
                        "&openid="+ openid;
                //再次获取微信用户信息
                client = new HttpClientUtils(path);
                client.get();
                content = client.getContent();
                contentMap = JSON.parseObject(content, Map.class);
                String nickName = contentMap.get("nickname").toString();
                String headimgurl = contentMap.get("headimgurl").toString();
                userInfo = new UserInfo();
                userInfo.setNickName(nickName);
                userInfo.setHeadImg(headimgurl);
                //超过七天，更新信息
                userInfoService.updateById(userInfo);
            }
        } catch (IOException e) {
            throw new SrbException(ResponseEnum.WEIXIN_CALLBACK_PARAM_ERROR);
        }
        //保存日志
        userInfoService.addLog(userInfo, request);
        String echoToken = JwtUtils.createToken(userInfo.getId(), userInfo.getNickName());
        return "redirect:" + WxLoginInfoProperties.REDIRECTURL + "?token=" + echoToken;
    }
}